module KeyExp (
    input clk_i,
    input rst_n_i,

    input MK_Valid_i,
    input [127:0] Key_i,


    output RK_Ready_o,
    output [1023:0] RoundKey_o
);

wire [31:0] CK[0:31] ;
//CK value table
assign CK[0] = 32'h00070E15, CK[1] = 32'h1C232A31, CK[2] = 32'h383F464D, CK[3] = 32'h545B6269;
assign CK[4] = 32'h70777E85, CK[5] = 32'h8C939AA1, CK[6] = 32'hA8AFB6BD, CK[7] = 32'hC4CBD2D9;
assign CK[8] = 32'hE0E7EEF5, CK[9] = 32'hFC030A11, CK[10] = 32'h181F262D, CK[11] = 32'h343B4249;
assign CK[12] = 32'h50575E65, CK[13] = 32'h6C737A81, CK[14] = 32'h888F969D, CK[15] = 32'hA4ABB2B9;
assign CK[16] = 32'hC0C7CED5, CK[17] = 32'hDCE3EAF1, CK[18] = 32'hF8FF060D, CK[19] = 32'h141B2229;
assign CK[20] = 32'h30373E45, CK[21] = 32'h4C535A61, CK[22] = 32'h686F767D, CK[23] = 32'h848B9299;
assign CK[24] = 32'hA0A7AEB5, CK[25] = 32'hBCC3CAD1, CK[26] = 32'hD8DFE6ED, CK[27] = 32'hF4FB0209;
assign CK[28] = 32'h10171E25, CK[29] = 32'h2C333A41, CK[30] = 32'h484F565D, CK[31] = 32'h646B7279;

wire [31:0] FK[0:3];
assign FK[0] = 32'hA3B1BAC6, FK[1] = 32'h56AA3350, FK[2] = 32'h677D9197, FK[3] = 32'hB27022DC;


wire [31:0] MK0 ;
wire [31:0] MK1 ;
wire [31:0] MK2 ;
wire [31:0] MK3 ;
assign MK0 = Key_i[127:96];
assign MK1 = Key_i[95:64];
assign MK2 = Key_i[63:32];
assign MK3 = Key_i[31:0];

reg [31:0] K[0:35] ;
always @(*) begin
    K[0] = MK0 ^ FK[0];
    K[1] = MK1 ^ FK[1];
    K[2] = MK2 ^ FK[2];
    K[3] = MK3 ^ FK[3];
end

reg [7:0] cnt;//round counter
reg MK_Valid_r;
wire RK_start;
wire rk_finished;
always @(posedge clk_i) begin
    if(!rst_n_i)
        MK_Valid_r <= 1'b0;
    else
        MK_Valid_r <= MK_Valid_i;
end
assign RK_start = (!MK_Valid_r) & MK_Valid_i;
always @(posedge clk_i ) begin
    if((!rst_n_i) || (RK_start)) begin
        cnt <= 8'b0;
    end
    else if(MK_Valid_i && !rk_finished) begin
        cnt <= cnt + 1;
    end
    else if (rk_finished) begin
        cnt <= 8'd32;
    end
end
assign rk_finished = (cnt == 8'd31) ;

//--------round key iterate control----------------------------------
reg [31:0] x0_i, x1_i, x2_i, x3_i;
reg [31:0] ck_i;
wire [31:0] rk_o;
Round_Fuction RK(
     .kgen_en(1'b1),     //1: 生成轮密钥 0： 生成加解密数据    
     .x0_i(x0_i),
     .x1_i(x1_i),
     .x2_i(x2_i),
     .x3_i(x3_i),
     .rk_i(ck_i),       // ck_i 
     .x4_o(rk_o)
);
always @(*) begin
    if(cnt == 0) begin
        x0_i = K[0];
        x1_i = K[1];
        x2_i = K[2];
        x3_i = K[3];
        ck_i = CK[0];        
    end
    else if(cnt == 1)begin
        x0_i = K[1];
        x1_i = K[2];
        x2_i = K[3];
        x3_i = K[4];
        ck_i = CK[1];
    end
    else if(cnt == 2) begin
        x0_i = K[2];
        x1_i = K[3];
        x2_i = K[4];
        x3_i = K[5];
        ck_i = CK[2];
    end
    else if(cnt == 3) begin
        x0_i = K[3];
        x1_i = K[4];
        x2_i = K[5];
        x3_i = K[6];
        ck_i = CK[3];
    end
    else if(cnt == 4) begin
        x0_i = K[4];
        x1_i = K[5];
        x2_i = K[6];
        x3_i = K[7];
        ck_i = CK[4];
    end
    else if(cnt == 5) begin
        x0_i = K[5];
        x1_i = K[6];
        x2_i = K[7];
        x3_i = K[8];
        ck_i = CK[5];
    end
    else if(cnt == 6) begin
        x0_i = K[6];
        x1_i = K[7];
        x2_i = K[8];
        x3_i = K[9];
        ck_i = CK[6];
    end
    else if(cnt == 7) begin
        x0_i = K[7];
        x1_i = K[8];
        x2_i = K[9];
        x3_i = K[10];
        ck_i = CK[7];
    end
    else if(cnt == 8) begin
        x0_i = K[8];
        x1_i = K[9];
        x2_i = K[10];
        x3_i = K[11];
        ck_i = CK[8];
    end
    else if(cnt == 9) begin
        x0_i = K[9];
        x1_i = K[10];
        x2_i = K[11];
        x3_i = K[12];
        ck_i = CK[9];
    end
    else if(cnt == 10) begin
        x0_i = K[10];
        x1_i = K[11];
        x2_i = K[12];
        x3_i = K[13];
        ck_i = CK[10];
    end
    else if(cnt == 11) begin
        x0_i = K[11];
        x1_i = K[12];
        x2_i = K[13];
        x3_i = K[14];
        ck_i = CK[11];
    end
    else if(cnt == 12) begin
        x0_i = K[12];
        x1_i = K[13];
        x2_i = K[14];
        x3_i = K[15];
        ck_i = CK[12];
    end
    else if(cnt == 13) begin
        x0_i = K[13];
        x1_i = K[14];
        x2_i = K[15];
        x3_i = K[16];
        ck_i = CK[13];
    end
    else if(cnt == 14) begin
        x0_i = K[14];
        x1_i = K[15];
        x2_i = K[16];
        x3_i = K[17];
        ck_i = CK[14];
    end
    else if(cnt == 15) begin
        x0_i = K[15];
        x1_i = K[16];
        x2_i = K[17];
        x3_i = K[18];
        ck_i = CK[15];
    end
    else if(cnt == 16) begin
        x0_i = K[16];
        x1_i = K[17];
        x2_i = K[18];
        x3_i = K[19];
        ck_i = CK[16];
    end
    else if(cnt == 17) begin
        x0_i = K[17];
        x1_i = K[18];
        x2_i = K[19];
        x3_i = K[20];
        ck_i = CK[17];
    end
    else if(cnt == 18) begin
        x0_i = K[18];
        x1_i = K[19];
        x2_i = K[20];
        x3_i = K[21];
        ck_i = CK[18];
    end
    else if(cnt == 19) begin
        x0_i = K[19];
        x1_i = K[20];
        x2_i = K[21];
        x3_i = K[22];
        ck_i = CK[19];
    end
    else if(cnt == 20) begin
        x0_i = K[20];
        x1_i = K[21];
        x2_i = K[22];
        x3_i = K[23];
        ck_i = CK[20];
    end
    else if(cnt == 21) begin
        x0_i = K[21];
        x1_i = K[22];
        x2_i = K[23];
        x3_i = K[24];
        ck_i = CK[21];
    end
    else if(cnt == 22) begin
        x0_i = K[22];
        x1_i = K[23];
        x2_i = K[24];
        x3_i = K[25];
        ck_i = CK[22];
    end
    else if(cnt == 23) begin
        x0_i = K[23];
        x1_i = K[24];
        x2_i = K[25];
        x3_i = K[26];
        ck_i = CK[23];
    end
    else if(cnt == 24) begin
        x0_i = K[24];
        x1_i = K[25];
        x2_i = K[26];
        x3_i = K[27];
        ck_i = CK[24];
    end
    else if(cnt == 25) begin
        x0_i = K[25];
        x1_i = K[26];
        x2_i = K[27];
        x3_i = K[28];
        ck_i = CK[25];
    end
    else if(cnt == 26) begin
        x0_i = K[26];
        x1_i = K[27];
        x2_i = K[28];
        x3_i = K[29];
        ck_i = CK[26];
    end
    else if(cnt == 27) begin
        x0_i = K[27];
        x1_i = K[28];
        x2_i = K[29];
        x3_i = K[30];
        ck_i = CK[27];
    end
    else if(cnt == 28) begin
        x0_i = K[28];
        x1_i = K[29];
        x2_i = K[30];
        x3_i = K[31];
        ck_i = CK[28];
    end
    else if(cnt == 29) begin
        x0_i = K[29];
        x1_i = K[30];
        x2_i = K[31];
        x3_i = K[32];
        ck_i = CK[29];
    end
    else if(cnt == 30) begin
        x0_i = K[30];
        x1_i = K[31];
        x2_i = K[32];
        x3_i = K[33];
        ck_i = CK[30];
    end
    else if(cnt == 31) begin
        x0_i = K[31];
        x1_i = K[32];
        x2_i = K[33];
        x3_i = K[34];
        ck_i = CK[31];
    end
    else begin
        x0_i = 32'b0;
        x1_i = 32'b0;
        x2_i = 32'b0;
        x3_i = 32'b0;
        ck_i = 32'b0;
    end
end



generate
    genvar i;
    for ( i= 0;i<32 ;i=i+1 ) begin
        always @(posedge clk_i ) begin
            if(!rst_n_i)
                K[i+4] <= 32'b0;
        else if (cnt == i && MK_Valid_i) 
                K[i+4] <= rk_o;
        end
    end
endgenerate


//-------output-----------------------------------
assign RK_Ready_o = (cnt == 8'd32);
// assign RoundKey_o = {K[35],K[34],...,K[4]};
generate
    genvar j;
    for (j = 0;j < 32 ; j = j +1) begin
        assign RoundKey_o[(j+1)*32-1:j*32] = K[j+4];
    end
endgenerate


endmodule //KeyExp
